package com.zhima.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhima.dto.ContestQuestionDTO;
import com.zhima.dto.FeignQuestionBasicInfoDTO;
import com.zhima.entity.OjContest;
import com.zhima.entity.OjQuestionBindContest;
import com.zhima.enums.QuestionScope;
import com.zhima.exception.ZhimaOjException;
import com.zhima.feignclient.QuestionFeignClient;
import com.zhima.mapper.OjQuestionBindContestMapper;
import com.zhima.service.OjContestService;
import com.zhima.service.OjQuestionBindContestService;
import com.zhima.util.AuthorizationUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

import static com.zhima.exception.ErrorCode.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zhima
 * @since 2024-01-18
 */
@Service
public class OjQuestionBindContestServiceImpl extends ServiceImpl<OjQuestionBindContestMapper, OjQuestionBindContest> implements OjQuestionBindContestService {

    @Autowired
    private QuestionFeignClient questionFeignClient;
    @Autowired
    private OjContestService ojContestService;
    @Autowired
    private OjQuestionBindContestMapper ojQuestionBindContestMapper;

    @Override
    public List<OjQuestionBindContest> listQuestionInfoByContestId(Long contestId) {
        return lambdaQuery().eq(OjQuestionBindContest::getContestId, contestId).orderByAsc(OjQuestionBindContest::getQuestionIndex).list();
    }

    @Override
    public boolean bindQuestionToContest(Long userId, OjQuestionBindContest contestBindQuestion) {
        OjContest byId = ojContestService.getById(contestBindQuestion.getContestId());
        AuthorizationUtil.isLoginUserResource(userId, byId.getHolderId());
        if (byId.getBeginTime().before(new Date())) {
            // 比赛已经开始，禁止修改题目配置
            throw new ZhimaOjException(CONTEST_HAS_BEGIN_NOT_ALLOW_UPDATE_QUESTION);
        }
        // 不允许重复增加题目
        if (lambdaQuery().eq(OjQuestionBindContest::getContestId, contestBindQuestion.getContestId()).eq(OjQuestionBindContest::getQuestionNumber, contestBindQuestion.getQuestionNumber()).count() > 0) {
            throw new ZhimaOjException(NOT_ALLOW_DUPLICATE_QUESTION);
        }
        Long questionId = questionFeignClient.getQuestionIdByQuestionNumber(contestBindQuestion.getQuestionNumber());
        FeignQuestionBasicInfoDTO feignQuestionBasicInfoDTO = questionFeignClient.queryQuestionBasicInfo(questionId);
        // 没有此题目
        if (feignQuestionBasicInfoDTO == null || feignQuestionBasicInfoDTO.getScope() == QuestionScope.PRIVATE) {
            throw new ZhimaOjException(NOT_FIND_QUESTION_BY_QUESTION_NUMBER);
        }
        // 题目索引
        contestBindQuestion.setQuestionIndex(byId.getQuestionNum());
        // 比赛题目数量增1
        ojContestService.updateQuestionNum(contestBindQuestion.getContestId(), true);
        contestBindQuestion.setQuestionId(questionId);
        // 保存
        return save(contestBindQuestion);
    }

    @Override
    public boolean changeQuestionIndex(Long userId, Long contestId, ContestQuestionDTO[] afterSequence) {
        OjContest ojContest = ojContestService.getById(contestId);
        AuthorizationUtil.isLoginUserResource(userId, ojContest.getHolderId());
        if (ojContest.getBeginTime().before(new Date())) {
            // 比赛已经开始，禁止修改题目配置
            throw new ZhimaOjException(CONTEST_HAS_BEGIN_NOT_ALLOW_UPDATE_QUESTION);
        }
        boolean success = true;
        for (int i = 0; i < afterSequence.length; i++) {
            success &= ojQuestionBindContestMapper.changeQuestionIndex(contestId, afterSequence[i].getQuestionNumber(), afterSequence[i].getMagnification(), i);
        }
        return success;
    }

    @Override
    public boolean unbindQuestionToContest(Long userId, Long contestId, Integer questionIndex) {
        OjContest ojContest = ojContestService.getById(contestId);
        AuthorizationUtil.isLoginUserResource(userId, ojContest.getHolderId());
        if (ojContest.getBeginTime().before(new Date())) {
            // 比赛已经开始，禁止修改题目配置
            throw new ZhimaOjException(CONTEST_HAS_BEGIN_NOT_ALLOW_UPDATE_QUESTION);
        }
        // 减少题单题目数量
        ojContestService.updateQuestionNum(ojContest.getId(), false);
        // 删除题目绑定
        lambdaUpdate().eq(OjQuestionBindContest::getContestId, ojContest.getId()).eq(OjQuestionBindContest::getQuestionIndex, questionIndex).remove();
        // 已经没有题目了，不需要更新索引
        if (ojContest.getQuestionNum() == 1) {
            return true;
        }
        // 更新题目索引
        // questionBindBank.getQuestionIndex()后的题目索引都要减1
        return ojQuestionBindContestMapper.decreaseQuestionIndex(ojContest.getId(), questionIndex);
    }
}
